<template>
  <div class="search-tree flex flex-column">
    <div v-if="treeTitle" class="search-tree-title flex-fixed">{{ treeTitle }}</div>
    <a-input-search
      v-model:value="searchValue"
      class="flex-fixed"
      style="margin: 8px 0"
      placeholder="搜索"
      @search="handleSearch"
    />
    <div
      ref="treeWrapper"
      class="search-tree-wrap flex-auto-height"
      style="box-sizing: content-box; width: 100%; overflow: auto"
    >
      <a-tree
        v-model:selectedKeys="selectedKeys"
        v-model:expandedKeys="expandedKeys"
        v-bind="$attrs"
        :tree-data="dataList"
        :field-names="fields"
        :auto-expand-parent="true"
        @select="handleSelect"
      />
    </div>
  </div>
</template>

<script>
import { debounce, get } from 'lodash-es';

function formatStr(str) {
  return String(str).trim().toLowerCase();
}

function deepSearch(val, list = [], fields) {
  if (!list || !list.length) return [];
  const res = [];
  const { title, children } = fields;
  for (const item of list) {
    const data = Object.assign({}, item);
    if (item[children] && item[children].length) {
      data[children] = deepSearch(val, item[children], fields);
    }
    if (formatStr(item[title]).indexOf(val) >= 0 || (data[children] && data[children].length)) {
      res.push(data);
    }
  }
  return res;
}

export default {
  name: 'SearchTree',
  emits: ['autoSelectFirst', 'change'],
  props: {
    treeTitle: { type: String, default: '' },
    treeData: { type: Array, default: () => [] },
    replaceFields: { type: Object, default: () => ({}) },
    autoSelectFirst: { type: Boolean, default: false },
  },
  data() {
    return {
      height: 100,
      searchValue: '',
      dataList: [],
      selectedKeys: [],
      expandedKeys: [],
    };
  },
  computed: {
    fields() {
      return Object.assign({ children: 'children', title: 'title', key: 'key' }, this.replaceFields);
    },
  },
  created() {
    this.$watch(
      () => this.treeData,
      debounce(function () {
        this.handleSearch();
        this.selectFirst();
      }, 300),
      { immediate: true }
    );
  },
  mounted() {
    this.height = this.$refs.treeWrapper.clientHeight;
  },
  methods: {
    selectFirst() {
      //  是否选中第一个
      if (this.dataList && this.dataList.length && this.autoSelectFirst) {
        const val = get(this.dataList, `[0].${this.fields.key}`);
        this.selectedKeys = val ? [val] : [];
        this.handleSelect(this.selectedKeys, { node: this.dataList[0] });
        this.$emit('autoSelectFirst');
      }
    },
    handleSelect(val, data) {
      const { title, key } = this.fields;
      this.$emit('change', {
        label: get(data, `node.${title}`),
        value: get(data, `node.${key}`),
      });
    },
    handleSearch() {
      if (!this.treeData || !this.treeData.length) {
        return;
      }
      const val = formatStr(this.searchValue);
      this.dataList = val ? deepSearch(val, this.treeData, this.fields) : this.treeData.slice();
      /* 默认只展开一二级 */
      this.expandedKeys = this.dataList.reduce((res, item) => {
        const { children, key } = this.fields;
        if (item && item[children] && item[children].length) {
          res = res.concat(item[children].map((subItem) => subItem[key]));
        }
        return res.concat([item[key]]);
      }, []);
    },
  },
};
</script>

<style lang="less">
.search-tree {
  height: 100%;
}
</style>
